package com.yiyi.credit.manage.sso.api.controller;

import com.yiyi.credit.manage.sso.common.CookieConstants;
import com.yiyi.credit.manage.sso.common.MD5Util;
import com.yiyi.credit.manage.sso.common.enums.PasswordErrorNums;
import com.yiyi.credit.manage.sso.common.enums.UserStatus;
import com.yiyi.credit.manage.sso.common.exception.ResponseCode;
import com.yiyi.credit.manage.sso.common.exception.ServiceException;
import com.yiyi.credit.manage.sso.common.page.Pagination;
import com.yiyi.credit.manage.sso.model.dto.CookieInfoDto;
import com.yiyi.credit.manage.sso.model.dto.response.Response;
import com.yiyi.credit.manage.sso.model.entity.*;
import com.yiyi.credit.manage.sso.model.system.UserAllInfo;
import com.yiyi.credit.manage.sso.service.inner.*;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;


@RefreshScope
@RestController
@RequestMapping("system/user")
public class SysUserController {

    private static final Logger logger = LoggerFactory.getLogger(SysUserController.class);

    private Map<String, Integer> passwordErrorNums = new HashMap<>();

    @Autowired
    SysUserService sysUserService;

    @Autowired
    SysUserInfoService sysUserInfoService;

    @Autowired
    SysRoleService sysRoleService;

    @Autowired
    SysUserRoleService sysUserRoleService;

    @Autowired
    TokenService tokenService;

    @Autowired
    ShopService shopService;



    @ApiOperation(value = "系统用户注册", notes = "创建系统用户")
    @ApiImplicitParams
        ({
            @ApiImplicitParam(name = "userName", value = "用户名", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "sysUserInfo", value = "系统用户个人信息", required = true, dataType = "SysUserInfo",
                paramType = "query")
        })
    @PostMapping(value = "register")
    public Object register(@RequestParam String userName,
                           @RequestParam String password,
                           @RequestParam Long status,
                           @RequestParam SysUserInfo sysUserInfo) throws Exception {
        if (StringUtils.isBlank(userName)) {
            throw new ServiceException(ResponseCode.USERNAME_NOTNULL);
        }
        if (StringUtils.isBlank(password)) {
            throw new ServiceException(ResponseCode.PWD_NOTNULL);
        }
        if (sysUserService.getUserByName(userName) != null) {
            throw new ServiceException(ResponseCode.USERNAME_REPEAT);
        }
        sysUserService.register(userName, password, status, sysUserInfo);
        return new Response<>();
    }


    @ApiOperation(value = "用户登录", notes = "系统用户登录")
    @ApiImplicitParams
        ({
            @ApiImplicitParam(name = "userName", value = "用户名", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String", paramType = "query"),
        })
    @PostMapping(value = "/loginSysUser")
    public Object loginSysUser(@RequestParam String userName, @RequestParam String password) throws Exception {

        logger.info("sso---用户{}正在登录", userName);


        SysUser sysUser = sysUserService.getUserByName(userName);

        if (sysUser == null) {
            throw new ServiceException(ResponseCode.USER_NOT_EXIST);
        }
        if (sysUser.getStatus().longValue() == UserStatus.DISABLE.getCode().longValue()) {
            throw new ServiceException(ResponseCode.USER_DISABLE);
        }

        //密码错误次数判断
        int checkPasswordErrorNums = passwordErrorNums.get(userName) == null ? 0 : passwordErrorNums.get(userName);
        if (checkPasswordErrorNums >= PasswordErrorNums.MAX.getCode()) {
            Long lockTime = sysUser.getLockTime();
            if (lockTime == null)
                lockTime = 0L;
            Long currTime = System.currentTimeMillis();
            if (lockTime + 86400000 < currTime) {
                passwordErrorNums.put(userName, PasswordErrorNums.DEFAULT.getCode());
                checkPasswordErrorNums = PasswordErrorNums.DEFAULT.getCode();
            } else {
                throw new ServiceException(ResponseCode.USER_LOCK);
            }
        }


        if (!MD5Util.checkPassword(password, sysUser.getPassword())) {
            passwordErrorNums.put(userName, ++checkPasswordErrorNums);

            if (passwordErrorNums.get(userName) == PasswordErrorNums.MAX.getCode().intValue()) {
                sysUser.setLockTime(new Date().getTime());
                sysUserService.updateSysUser(sysUser);
            }
            throw new ServiceException(ResponseCode.PWD_WRONG);
        } else {
            passwordErrorNums.put(userName, PasswordErrorNums.DEFAULT.getCode());
        }


        //token
        String token = tokenService.generatorToken(sysUser.getId(), CookieConstants.TIMEOUT);
        //返回信息
        CookieInfoDto tokenInfo = new CookieInfoDto();
        tokenInfo.setToken(token);
        tokenInfo.setName(CookieConstants.NAME);
        tokenInfo.setSecure(CookieConstants.SECURE);
        tokenInfo.setMaxAge(CookieConstants.MAX_AGE);
        tokenInfo.setDomain(CookieConstants.DOMAIN);
        tokenInfo.setPath(CookieConstants.PATH);
        tokenInfo.setUserId(sysUser.getId());
        tokenInfo.setShopId(sysUser.getShopId());
        return new Response<>(tokenInfo);
    }

    @ApiOperation(value = "获取系统用户信息", notes = "获取系统用户信息")
    @ApiImplicitParams
        ({
            @ApiImplicitParam(name = "sysUserId", value = "用户id", required = true, dataType = "Long", paramType = "query")
        })
    @PostMapping(value = "/getSysUserInfo")
    public Object getSysUserInfo(@RequestParam Long sysUserId) throws Exception {

        SysUser sysUser = sysUserService.getSysUserById(sysUserId);
        return new Response<>(sysUser);
    }


    @ApiOperation(value = "密码修改", notes = "系统用户密码修改")
    @ApiImplicitParams
        ({
            @ApiImplicitParam(name = "userName", value = "用户名", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "oldPwd", value = "旧密码", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "newPwd", value = "新密码", required = true, dataType = "String", paramType = "query"),
        })
    @PostMapping(value = "/changePwdSysUser")
    public Object changePwdSysUser(@RequestParam String userName,
                                   @RequestParam String oldPwd,
                                   @RequestParam String newPwd) throws Exception {
        if (StringUtils.isBlank(oldPwd)) {
            throw new ServiceException(ResponseCode.PWD_NOTNULL);
        }
        if (StringUtils.isBlank(newPwd)) {
            throw new ServiceException(ResponseCode.PWD_NOTNULL);
        }
        if (oldPwd.equals(newPwd)) {
            throw new ServiceException(ResponseCode.PWD_REPEAT);
        }
        SysUser sysUser = sysUserService.getUserByName(userName);
        if (sysUser == null) {
            throw new ServiceException(ResponseCode.USER_NOT_EXIST);
        }
        if (!MD5Util.encoderByMd5(oldPwd).equals(sysUser.getPassword())) {
            throw new ServiceException(ResponseCode.OLD_PWD_WRONG);
        }
        sysUser.setPassword(MD5Util.encoderByMd5(newPwd));
        sysUserService.updateSysUser(sysUser);
        return new Response<>();
    }

    @ApiOperation(value = "退出", notes = "退出删除登录token")
    @ApiImplicitParams
        ({
            @ApiImplicitParam(name = "tokenVal", value = "token值", required = true, dataType = "String", paramType = "query")
        })
    @PostMapping("/logout")
    public Object logout(@RequestParam(name = "tokenVal") String tokenVal) throws Exception {
        tokenService.delToken(tokenVal);
        return new Response<>();
    }

    @ApiOperation(value = "验证Token的有效性", notes = "验证Token的有效性")
    @ApiImplicitParams
        ({
            @ApiImplicitParam(name = "token", value = "token值", required = true, dataType = "String", paramType = "query")
        })
    @PostMapping(value = "/authToken")
    public Object authToken(@RequestParam(name = "token") String token) throws Exception {

        Boolean isValid = tokenService.verifyToken(token);
        if (!isValid) {
            return new Response<>(ResponseCode.TOKEN_WRONG);
        }
        return new Response<>();
    }

    @ApiOperation(value = "根据Token获取用户信息", notes = "根据Token获取用户信息")
    @ApiImplicitParams
        ({
            @ApiImplicitParam(name = "token", value = "token值", required = true, dataType = "String", paramType = "query")
        })
    @PostMapping(value = "/getSysUserByToken")
    public Object getSysUserByToken(@RequestParam(name = "token") String token) throws Exception {
        Boolean isValid = tokenService.verifyToken(token);
        if (!isValid) {
            return new Response<>(ResponseCode.TOKEN_WRONG);
        }
        Long sysUserId = tokenService.getUidByToken(token);
        SysUser sysUser = sysUserService.getSysUserById(sysUserId);
        return new Response<>(sysUser);
    }


    @ApiOperation(value = "根据Token，系统Id获取用户完整信息", notes = "根据Token，系统Id获取用户完整信息")
    @ApiImplicitParams
        ({
            @ApiImplicitParam(name = "token", value = "token值", required = true, dataType = "String", paramType = "query")
        })
    @PostMapping(value = "/getSysUserInfoByToken")
    public Object getSysUserInfoByToken(@RequestParam(name = "token") String token,
                                        @RequestParam(name = "sysInfoId") Long sysInfoId) throws Exception {
        Boolean isValid = tokenService.verifyToken(token);
        if (!isValid) {
            return new Response<>(ResponseCode.TOKEN_WRONG);
        }
        Long sysUserId = tokenService.getUidByToken(token);
        SysUser sysUser = sysUserService.getSysUserById(sysUserId);//user表
        SysUserInfo sysUserInfo = sysUserInfoService.getSysInfoByUserId(sysUserId).get(0);//userInfo表
        SysUserRole sysUserRole = sysUserRoleService.getSysUserRole(sysUserId, sysInfoId).get(0);//userrole
        SysRole sysRole = sysRoleService.getSysRoleById(sysUserRole.getRoleId());
        SysUserAllInfo sysUserAllInfo = buildSysUserAllInfoUseOtherObject(sysUser, sysUserInfo, sysUserRole, sysRole);
        return new Response<>(sysUserAllInfo);
    }

    private SysUserAllInfo buildSysUserAllInfoUseOtherObject(SysUser sysUser, SysUserInfo sysUserInfo, SysUserRole sysUserRole, SysRole sysRole) {
        Shop shop = shopService.getShopById(sysUser.getShopId());
        SysUserAllInfo sysUserAllInfo = new SysUserAllInfo();
        sysUserAllInfo.setId(sysUser.getId());
        sysUserAllInfo.setShopId(sysUser.getShopId());
        sysUserAllInfo.setStatus(sysUser.getStatus());
        sysUserAllInfo.setUserName(sysUser.getUserName());
        sysUserAllInfo.setPassWord(sysUser.getPassword());
        sysUserAllInfo.setRealName(sysUserInfo.getRealName());
        sysUserAllInfo.setPhone(sysUserInfo.getPhone());
        sysUserAllInfo.setSex(sysUserInfo.getSex());
        sysUserAllInfo.setAddress(sysUserInfo.getAddress());
        sysUserAllInfo.setIsSubStation(sysUserRole.getSubStationId());
        sysUserAllInfo.setRoleName(sysRole.getRoleName());
        sysUserAllInfo.setRoleId(sysRole.getId());
        sysUserAllInfo.setCityCode(Objects.isNull(shop)?"":shop.getSname());
        return sysUserAllInfo;
    }

    @ApiOperation(value = "获取TokenKey", notes = "获取TokenKey")
    @ApiImplicitParams({})
    @PostMapping(value = "/getTokenKey")
    public Object getTokenKey() throws Exception {
        Map<String, String> keyMap = new HashMap<>();
        keyMap.put("tokenKey", CookieConstants.NAME);
        return new Response<>(keyMap);
    }



    @PostMapping(value = "/getUserAllInfoList")
    public Pagination getUserAllInfoList(Long sysInfoId,
                                         String userName,
                                         String realName,
                                         Long roleNameId,
                                         Long status,
                                         Integer pageIndex, Integer pageSize) throws Exception {
        Pagination pagination = new Pagination(pageIndex, pageSize);
        //return new Response<>(sysUserService.getUserAllInfoList(sysInfoId, pagination));
        return sysUserService.getUserAllInfoList(sysInfoId, userName, realName, roleNameId, status, pagination);
    }


    @PostMapping(value = "/getUserInfoByIds")
    public List<UserAllInfo> getUserInfoByIds(Long sysInfoId, String ids) throws Exception {

        return sysUserService.getUserInfoByIds(sysInfoId, ids);
    }



    @PostMapping(value = "/getSysUserId")
    public Long getSysUserId(String userName) throws Exception {
        SysUser sysUser = sysUserService.getSysUserByUserName(userName).get(0);
        return sysUser.getId();
    }



    @PostMapping(value = "/getPhoneByUserName")
    public Map<String,String> getPhoneByUserName(String userName) throws Exception {
        // SysUser sysUser = sysUserService.getSysUserByUserName(userName).get(0);
        // SysUserInfo sysUserInfo = sysUserInfoService.getSysInfoByUserId(sysUser.getId()).get(0);
        // return sysUserInfo.getPhone();
        return sysUserService.getSysUserByUserName1(userName);
    }


    @PostMapping(value = "/updatePhone")
    public Object updatePhone(Long sysInfoId,
                              String userName,
                              String password,
                              String newPhone) throws Exception {

        //条件判断
        SysUser sysUser = sysUserService.getUserByName(userName);
        if (sysUser == null) {
            return new Response<>(ResponseCode.USER_NOT_EXIST);
        }
        if (!MD5Util.checkPassword(password, sysUser.getPassword())) {
            return new Response<>(ResponseCode.PWD_WRONG);
        }

        SysUserInfo sysUserInfo = sysUserInfoService.getSysInfoByUserId(sysUser.getId()).get(0);
        if (sysUserInfo == null) {
            throw new Exception("查询用户失败");
        }

        sysUserInfo.setPhone(newPhone);
        sysUserInfoService.updateSysUserInfo(sysUserInfo);


        return new Response<>(ResponseCode.SUCCESS);
    }

    @RequestMapping("/getEmailByUsername")
    public String getEmailByUsername(@RequestParam("username") String username) throws ServiceException {
        String email = sysUserInfoService.getEmailByUsername(username);
        if (StringUtils.isBlank(email)) {
            throw new ServiceException("email是空的");
        } else {
            return email;
        }
    }
}